/*
 * @depends component.js, Panel.js
 */
QFinance.component.CategoriesEditPanel = Ext.extend( QFinance.ui.Panel, {
    // Configuration
    layout: 'fit',
    canAddCategory: true,
    canEditCategory: true,
    canRemoveCategory: true,
    categoryRecord: null,
    autoSelectCategoryID: null,
    selectingCategory: false,
	
    // Localization
    addCategoryText: 'Add',
    addCategoryToolTipText: 'Add a new category',
    editCategoryText: 'Edit',
    editCategoryToolTipText: 'Edit selected category',
    removeCategoryText: 'Remove',
    removeCategoryToolTipText: 'Remove selected category',
    categoriesText: 'Categories',
    removeQuestionTitle: 'Remove category',
    removeQuestionMsg: 'Would you like to remove selected accounts?',
    editInformationTitle: 'Edit account',	
    editInformationMsg: 'Please select a category to edit.',    
    addInformationTitle: 'Add category',
    addInformationMsg: 'Please select a category or root node.',
    removeInformationTitle: 'Remove category',
    removeInformationMsg: 'Please select a category to remove.',
	
    // IDs    
    selectCategoryIDID: null,
	
    // Components
    treePanel: null,
	
    constructor: function(config) {
        Ext.apply(this, config);
		
        this.createCategoryRecord();
        
        this.treeLoaderIDs = [];
		
        QFinance.component.CategoriesEditPanel.superclass.constructor.call(this);
    },
	
    initComponent: function() {
        var treePanelConfig = this.getTreePanelConfig();
		
        this.treePanel = new Ext.tree.TreePanel(treePanelConfig);				
        this.items = [ this.treePanel ];		
		
        if (this.canAddCategory || this.canEditCategory || this.canRemoveCategory)
            Ext.apply(this,{
                tbar: this.getTopBarConfig()
            });
		
        QFinance.component.CategoriesEditPanel.superclass.initComponent.call(this);
    },
	
    getTopBarConfig: function() {
        var topBarConfig = {
            items: this.getTopBarItemsConfig()	
        };		
		
        return topBarConfig;
    },
		
    getTopBarItemsConfig: function() {
        var topBarItemsConfig = [];
		
        if (this.canAddCategory) {
            topBarItemsConfig.push({
                text: this.addCategoryText,
                tooltip: this.addCategoryToolTipText,
                iconCls: 'fugue-plus-circle',
                scope: this,
                handler: function() {
                    var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                    if (selectedNode) {
                        var parentCategoryID = selectedNode.id == 'root' ? null : selectedNode.id;
                        var category = new this.categoryRecord({
                            parentCategoryID: parentCategoryID
                        });
                        var newCategory = new QFinance.component.CategoryEditWindow({
                            renderTo: this.getEl(),
                            constrain: true,
                            modal: true,                		
                            record: category,
                            autoLoadRecord: true,
                            listeners: {
                                scope: this,
                                save: function(record) {
                                    this.createCategory(record);
                                }
                            }
                        });
                        newCategory.show();
                    } else {
                        var information = new QFinance.ui.MessageBox();
                        information.show({
                            title: this.addInformationTitle,
                            msg: this.addInformationMsg,
                            buttons: Ext.MessageBox.OK,
                            renderTo: this.body,
                            icon: Ext.MessageBox.INFO
                        });
                    }              	
                }
            });
        }
		
        if (this.canEditCategory) {
            topBarItemsConfig.push({
                text: this.editCategoryText,
                tooltip: this.editCategoryToolTipText,
                iconCls: 'fugue-pencil',
                scope: this,
                handler: function() {
                    var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                    if (selectedNode && selectedNode.parentNode ) {
                        var category = this.loadCategoryFromNode( selectedNode );                		
                        var editCategory = new QFinance.component.CategoryEditWindow({
                            renderTo: this.getEl(),
                            constrain: true,
                            modal: true,                		
                            record: category,
                            autoLoadRecord: true,
                            isNew: false,
                            listeners: {
                                scope: this,
                                save: function(record) {
                                    this.updateCategory(record);
                                }
                            }
                        });
                        editCategory.show();
                    } else {
                        var information = new QFinance.ui.MessageBox();
                        information.show({
                            title: this.editInformationTitle,
                            msg: this.editInformationMsg,
                            buttons: Ext.MessageBox.OK,
                            renderTo: this.body,
                            icon: Ext.MessageBox.INFO
                        });
                    }               	
                }
            });
        }
		
        if (this.canRemoveCategory) {
            topBarItemsConfig.push({
                text: this.removeCategoryText,
                tooltip: this.removeCategoryToolTipText,
                iconCls: 'fugue-minus-circle',
                scope: this,
                handler: function() {
                    var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                    if (selectedNode && selectedNode.parentNode ) {
                        var category = this.loadCategoryFromNode( selectedNode );                		
                        this.destroyCategory( category );
                    } else {
                        var information = new QFinance.ui.MessageBox();
                        information.show({
                            title: this.removeInformationTitle,
                            msg: this.removeInformationMsg,
                            buttons: Ext.MessageBox.OK,
                            renderTo: this.body,
                            icon: Ext.MessageBox.INFO
                        });
                    }
                }
            });
        }
		
        return topBarItemsConfig;
    },
	
    getTreePanelConfig: function() {
        var treePanelConfig = {
            enableDD: true,
            autoScroll: true,
            root: {
                id: 'root',
                text: this.categoriesText
            },
            loader: new Ext.tree.TreeLoader({
                directFn: QFinance.Remoting.CategoriesEditPanelAction.getCategoryTree,
                listeners: {
                    scope: this,
                    beforeload: function(treeLoader, node, callback) {
                        treeLoader.failure = false;
                        this.treeLoaderIDs.push(this.getProcessStatusManager().start([this]));
                    },
                    load: function(treeLoader, node, response) {
                        if (!treeLoader.failure) {
                            this.getProcessStatusManager().success(this.treeLoaderIDs.pop());                            
                            this.getProcessStatusManager().success(this.selectCategoryIDID);
                        }
                    },
                    loadexception: function(treeLoader, node, response) {
                        treeLoader.failure = true;
                        var message = '';
                        var where = '';
                        if (response.responseText) {
                            message = response.responseText.message;
                            if (response.responseText.type == 'exception')
                                where = response.responseText.where;
                        } else {
                            message = 'Unable to connect to the server.';
                        }
                        this.getProcessStatusManager().error(this.treeLoaderIDs.pop(), message);                        
                        this.getProcessStatusManager().error(this.selectCategoryIDID, message);                          
                        QFinance.service.DeveloperService.log('TreeLoader failure: ' + message + ' where\n' + where);
                    }
                }
            }),	        
            dropConfig: {
                allowParentInsert: true
            },
            listeners: {
                scope: this,
                beforemovenode: this.beforeMoveNode,
                movenode: this.moveNode
            }
        };
		
        return treePanelConfig;
    },
	
    beforeMoveNode: function() {
        return this.canEditCategory;
    },
	
    moveNode: function(tree, node, oldParent, newParent, index) {
        var moveNodeID = this.getProcessStatusManager().start([this.treePanel]);
        var callback = function(result, event) {
            var message = '';
            var where = '';
            var failure = false;
			
            if (result) {
                if (result.success) {
                    this.getProcessStatusManager().success(moveNodeID);
                } else {
                    failure = true;						
                    message = result.message;
                    if (result.type == 'exception')
                        where = result.where;
                }            
            } else {
                failure = true;
                message = event.message;
            }
			
            if (failure) {
                this.getProcessStatusManager().error(moveNodeID, message);                
                QFinance.service.DeveloperService.log('Direct call failure: ' + message + ' where\n' + where);
                this.treePanel.getRootNode().reload();
            }            
        };                			
				
        if (newParent.id == 'root')
            QFinance.Remoting.CategoriesEditPanelAction.clearParentCategory( node.id, callback, this );
        else
            QFinance.Remoting.CategoriesEditPanelAction.setParentCategory( node.id, newParent.id, callback, this );		
    },
	
    createCategoryRecord: function() {
        this.categoryRecord = Ext.data.Record.create([
        {
            name: 'id', 
            type: 'int'
        },
        {
            name: 'categoryName', 
            allowBlank: false
        },
        {
            name: 'parentCategoryID', 
            type: 'int'
        }
        ]);
    },
	
    createCategory: function( record ) {
        var createCategoryID = this.getProcessStatusManager().start(this.treePanel);        
        QFinance.Remoting.CategoriesEditPanelAction.create(record, function(result, event) {
            var message = '';
            var where = '';
            var failure = false;
			
            if (result) {
                if (result.success) {
                    this.getProcessStatusManager().success(createCategoryID);
                    var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                    if (selectedNode) {
                        selectedNode.reload(function() {
                            var node = this.treePanel.getNodeById(result.id);
                            node.select();
                        }, this);
                    }		
                } else {
                    failure = true;						
                    message = result.message;
                    if (result.type == 'exception')
                        where = result.where;
                }            
            } else {
                failure = true;
                message = event.message;
            }
			
            if (failure) {
                this.getProcessStatusManager().error(createCategoryID, message);                
                QFinance.service.DeveloperService.log('Direct call failure: ' + message + ' where\n' + where);
            }
        }, this);
    },
	
    updateCategory: function( record ) {
        var updateCategoryID = this.getProcessStatusManager().start([this.treePanel]);
        QFinance.Remoting.CategoriesEditPanelAction.update(record, function(result, event) {
            var message = '';
            var where = '';
            var failure = false;
			
            if (result) {
                if (result.success) {
                    this.getProcessStatusManager().success(updateCategoryID);                    
                    var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                    if (selectedNode) {
                        selectedNode.parentNode.reload(function() {
                            var node = this.treePanel.getNodeById(record.get('id'));
                            node.select();
                        }, this);            		
                    }		
                } else {
                    failure = true;						
                    message = result.message;
                    if (result.type == 'exception')
                        where = result.where;
                }            
            } else {
                failure = true;
                message = event.message;
            }
			
            if (failure) {
                this.getProcessStatusManager().error(updateCategoryID, message);                
                QFinance.service.DeveloperService.log('Direct call failure: ' + message + ' where\n' + where);
            }      
        }, this);		
    },
	
    destroyCategory: function( record ) {
        var question = new QFinance.ui.MessageBox();
        question.show({
            title: this.removeQuestionTitle,
            msg: this.removeQuestionMsg,
            buttons: question.YESNO,
            icon: question.QUESTION,
            scope: this,
            fn: function(btn) {
                if (btn == 'yes') {
                    var destroyCategoryID = this.getProcessStatusManager().start([this.treePanel]);
                    QFinance.Remoting.CategoriesEditPanelAction.destroy(record, function(result, event) {
                        var message = '';
                        var where = '';
                        var failure = false;
						
                        if (result) {
                            if (result.success) {
                                this.getProcessStatusManager().success(destroyCategoryID);
                                var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
                                if (selectedNode) {
                                    selectedNode.parentNode.reload();            		
                                }		
                            } else {
                                failure = true;						
                                message = result.message;
                                if (result.type == 'exception')
                                    where = result.where;
                            }            
                        } else {
                            failure = true;
                            message = event.message;
                        }
						
                        if (failure) {
                            this.getProcessStatusManager().error(destroyCategoryID, message);                            
                            QFinance.service.DeveloperService.log('Direct call failure: ' + message + ' where\n' + where);
                        }    
                    }, this);	
                }								   
            },
            renderTo: this.body					   
        });
    },
	
    loadCategoryFromNode: function( node ) {
        var parentCategoryID = node.parentNode.id == 'root' ? null : node.parentNode.id;
        var category = new this.categoryRecord({
            id: node.id,
            categoryName: node.text,
            parentCategoryID: parentCategoryID
        });
		
        return category;
    },
	
    getSelectedCategory: function() {
        var selectedNode = this.treePanel.getSelectionModel().getSelectedNode();                        	                    	
        if (selectedNode) {
            if (selectedNode.parentNode)
                return this.loadCategoryFromNode(selectedNode);
        }
        return null;
    },
	
    selectCategoryID: function( categoryID ) {
        var categoryFound = false;

        this.treePanel.on('expandnode', function(node) {
            if (node.id == categoryID) {
                node.selectSilent();
                categoryFound = true;
            }
        }, this);
        
        var checkFunction = function() {
            if (categoryFound) {
                this.treePanel.un('beforeload', checkFunction, this);
                return false;
            } else {
                return true;
            }
        }; 
        this.treePanel.on('beforeload', checkFunction, this);       
        this.treePanel.root.expand(true);
    },
	
    onRender: function(ct, position) {
        QFinance.component.CategoriesEditPanel.superclass.onRender.call(this,ct, position);
        if (this.autoSelectCategoryID)
            this.selectCategoryID( this.autoSelectCategoryID );		
    }
});
Ext.reg('QFinance.component.CategoriesEditPanel', QFinance.component.CategoriesEditPanel);